var Substance = function() {};

Substance.prototype.initialize = function() {};

Substance.prototype.intersect = function() {return IntersectResult.noHit;};

Substance.prototype.isIntersect = function() {return false;};

var Sphere = function(center, radius) {
	this.center = center;
	this.radius = radius;
	this.vn = new Vector3(0, -1, 0);
	this.ve = new Vector3(1, 0, 1).normalize();
	this.vc =this.vn.cross(this.ve);
};

Sphere.prototype = new Substance();

Sphere.prototype.initialize = function() {
	this.sqrRadius = this.radius * this.radius;
};

Sphere.prototype.intersect = function(ray) {
	var v = ray.origin.subtract(this.center);
	var DdotV = ray.direction.dot(v);
	var a0 = v.sequare() - this.sqrRadius;
	var discr = DdotV * DdotV - a0;
	if (discr < 0) {
		return IntersectResult.noHit;
	}
	var result = new IntersectResult();
	var disSqrt = Math.sqrt(discr);
	var d1 = -DdotV - disSqrt;
	var d2 = -DdotV + disSqrt;
	if(d1 > 0.0001) {
		result.distance = d1;
		result.dir = 1;
	} else if(d2 > 0.0001) {
		result.distance = d2;
		result.dir = -1;
	} else {
		return IntersectResult.noHit;
	}
	result.position = ray.getPoint(result.distance);
	result.normal = result.position.subtract(this.center).normalize();
	if(result.dir == -1) {
		result.normal = result.normal.negate();
	}
	result.geometry = this;
	return result;
};

Sphere.prototype.isIntersect = function(ray) {
	var v = ray.origin.subtract(this.center);
	var DdotV = ray.direction.dot(v);
	var a0 = v.sequare() - this.sqrRadius;
	var discr = DdotV * DdotV - a0;
	if (discr < 0) {
		return false;
	}
	var result = new IntersectResult();
	var disSqrt = Math.sqrt(discr);
	var d1 = -DdotV - disSqrt;
	var d2 = -DdotV + disSqrt;
	if(d1 > 0.0001) {
		return true;
	} else if(d2 > 0.0001) {
		return true;
	} else {
		return false;
	}
};


var Plane = function(normal, d) {
	this.normal = normal;
	this.d = d;
};

Plane.prototype = new Substance();

Plane.prototype.initialize = function() {
	var up;
	if(this.normal.x ==0 && this.normal.y == 0) {
		if(this.normal.z > 0) {
			up = new Vector3(0, -1, 0);
		} else {
			up = new Vector3(0, 1, 0);
		}
	}else{
		up = new Vector3(0, 0, 1);
	}
	this.right = up.cross(this.normal);
	this.up = this.right.cross(this.normal).negate();
	this.position = this.normal.multiply(this.d);
};

Plane.prototype.intersect = function(ray) {
	var a = ray.direction.dot(this.normal);
	if(a >= 0) {
		return IntersectResult.noHit;
	}
	var d = this.normal.dot(ray.origin.subtract(this.position));
	var result = new IntersectResult();
	result.geometry = this;
	result.distance = -d / a;
	result.position = ray.getPoint(result.distance);
	result.normal = this.normal;
	result.tt = true;
	return result;
};

Plane.prototype.isIntersect = function(ray) {
	var a = ray.direction.dot(this.normal);
	if(a >= 0) {
		return false;
	}
	return true;
};

var IntersectResult = function(){
	this.geometry = null;
	this.distance = 0;
	this.position = Vector3.zero;
	this.normal = Vector3.zero;
};

IntersectResult.noHit = new IntersectResult();